﻿using Abp.AutoMapper;
using Abp.Linq.Extensions;
using RMM.Core.Evaluates;
using RMM.Core.Massagistes;
using RMM.Core.Orders;
using RMM.Core.UserService;
using RMM.Evaluates.Dtos;
using RMM.FrameWork;
using RMM.Massagists.Dtos;
using RMM.UserAppService.Dtos;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace RMM.Massagists
{
    public class MassagistAppService : IMassagistAppService
    {
        private readonly IUserService _userService;
        private readonly IMassagistService _massagistService;
        private readonly IEvaluateService _evaluateService;
        private readonly IEvaluateCateService _evaluateCateService;
        private readonly IOrderService _orderService;

        public MassagistAppService(IUserService userService
            , IEvaluateService evaluateService
            , IOrderService orderService
            , IMassagistService massagistService
            , IEvaluateCateService evaluateCateService)
        {
            _userService = userService;
            _evaluateService = evaluateService;
            _orderService = orderService;
            _massagistService = massagistService;
            _evaluateCateService = evaluateCateService;
        }


        /// <summary>
        /// 获取店铺某一时间段空闲的技师
        /// </summary>
        /// <param name="shopId"></param>
        /// <param name="StartTime"></param>
        /// <param name="EndTime"></param>
        /// <param name="Skip"></param>
        /// <returns></returns>
        public async Task<ResultDto> GetFreeMassagistAsync(int shopId,DateTime StartTime,DateTime EndTime,int Skip)
        {
            var massagistList = await _massagistService.GetFreeMassagistAsync(shopId, StartTime, EndTime);
            return ResultDto.Success(massagistList.OrderByDescending(p=>p.Id).Skip(Skip * 10).Take(10));
        }


        public async Task<ResultDto> GetMassagistList(MassagistInputDto dto)
        {
            var eval = (await _evaluateService.GetAll()).Where(p=>p.ObjectType == 0);

            var massagist = (await _massagistService.GetAll())
                .WhereIf(CommonHelper.Check(dto.Id), p => p.Id == dto.Id)
                .WhereIf(CommonHelper.Check(dto.ShopId), p => p.ShopId == dto.ShopId)
                .WhereIf(CommonHelper.Check(dto.Sex),p=>p.Sex == dto.Sex)
                .MapTo<List<MassagistDto>>();
            var masList = massagist.Select(x => x.MassagistId).ToList();
            var massExtend = _massagistService.GetMassagistProjectRepository().GetAll()
                .Where(p => masList.Contains(p.MassagistId))
                .ToList();
            var evalCate = (await _evaluateCateService.GetAll())
                .Where(p => p.Type == 0);
            var massProj = _massagistService.GetMassagistProjectRepository().GetAll()
                .WhereIf(CommonHelper.Check(dto.CateId), p => p.CateId == dto.CateId)
                .WhereIf(CommonHelper.Check(dto.PriceStart) && CommonHelper.Check(dto.PriceEnd), p => p.Price >= dto.PriceStart && p.Price <= dto.PriceEnd);

            massagist.ForEach(p =>
            {
                List<int> cateList = eval.Where(x => x.ObjectId == p.Id).Select(s => s.CateList).FirstOrDefault()?.Split(',').Select(int.Parse).ToList();

                p.Price = massProj.FirstOrDefault(x => x.MassagistId == p.MassagistId).Price;
                p.ProjectTime = massProj.FirstOrDefault(x => x.MassagistId == p.MassagistId).ProjectTime;
                p.Addition = massProj.FirstOrDefault(x => x.MassagistId == p.MassagistId).Addition;
                p.MakeNum = massagist.Count(x => x.MassagistId == p.MassagistId);
                p.EvaluateCates = cateList == null ? new List<string>() : evalCate.WhereIf(cateList != null, e => cateList.Contains(e.Id)).Select(e => e.CateContent).ToList();
            });

            var share = (await _massagistService.GetShareMassagistListAsync())
                .WhereIf(CommonHelper.Check(dto.ShopId), p => p.ShopId == dto.ShopId)
                .Select(p => p.MassagistId)
                .Distinct()
                .ToList();

            var list = massagist
                .OrderByDescending(p => p.Id)
                .Skip(dto.Skip * 10)
                .Take(10)
                .MapTo<List<MassagistDto>>();

            list.ForEach(p =>
            {
                p.Evaluate = eval.Where(x => x.ObjectId == p.Id).OrderByDescending(x => x.CreationTime).FirstOrDefault().MapTo<EvaluateDto>();
                p.EvaluateNum = eval.Where(x => x.ObjectId == p.Id).OrderByDescending(x => x.CreationTime).Count();
                var mos = 0;
                try
                {
                    mos = eval.Where(x => x.ObjectId == p.Id).Sum(x => x.Star) / p.EvaluateNum;
                }
                catch
                {
                    mos = 0;
                }
                p.MOS = mos;
                if (share.Contains(p.Id))
                {
                    p.IsShare = 1;
                }
            });

            Func<MassagistDto, object> func = p => p.Id;
            switch (dto.OrderType)
            {
                case 0:
                    func = p => p.MOS;
                    break;
                case 1:
                    GetDistance();
                    return ResultDto.Success(list.OrderBy(p=>p.Rice).Skip(dto.Skip).Take(10).ToList());
                case 2:
                    func = p => p.EvaluateNum;
                    break;
                case 3:
                    return ResultDto.Success(list = list.OrderBy(p=>p.Price).Skip(dto.Skip).Take(10).ToList());
                case 4:
                    func = p => p.Price;
                    break;
                default:
                    break;
            }

            return ResultDto.Success(list.OrderByDescending(func).Skip(dto.Skip).Take(10).ToList());

            void GetDistance()
            {
                list.ForEach(async p =>
                {
                    var str = string.Format("https://apis.map.qq.com/ws/distance/v1/?from={0},{1}&to={2},{3}&key=ZCQBZ-XTB34-OZEUE-XICUT-EY5ST-ZPB6Z", dto.Latitude, dto.Longitude, p.Latitude, p.Longitude);
                    var data = await CommonHelper.GetAsync<MassagistDistanceOutputJson>(str);
                    p.Rice = data.result.elements[0].distance;
                });
            }
        }


        public async Task<ResultDto> GetMassagistAsync(long massagistId)
        {
            //技师
            var massagist = (await _massagistService.GetAll())
                .FirstOrDefault(p => p.Id == massagistId);
            //项目
            var massProj = await _massagistService.GetMassagistProjectAsync();
            //评价
            var evaluates = (await _evaluateService.GetAll()).Where(p => p.ObjectType == 0 && p.ObjectId == massagistId);
            //共享
            var share = (await _massagistService.GetShareMassagistListAsync())
                .Count(p=>p.MassagistId == massagistId);

            if (massagist == null)
            {
                return default;
            }
            var dto = massagist.MapTo<MassagistDto>();
            var eval = evaluates.OrderByDescending(p => p.Id).FirstOrDefault();
            dto.Evaluate.Star = eval?.Star ?? 0;
            dto.Evaluate.Content = eval?.Content;
            dto.EvaluateCount = evaluates.Count();
            dto.OrderNum = (await _orderService.GetAll()).Where(p => p.Status == 4 && p.MassagistId == dto.MassagistId).Count();
            dto.MassagistProject = massProj.Where(p => p.MassagistId == dto.MassagistId)?.MapTo<List<MassagistProjectDto>>();
            dto.IsShare = share > 0 ? 1 : 0;

            return ResultDto.Success(dto);
        }
    }
}
